/*
 * TestMsjReceptor.cpp
 *
 *  Created on: 19/02/2010
 *      Author: San Martín, Matías I.
 */
#include <unistd.h>
#include <sstream>

#include "MockMiddlewareIO.h"

#include "../../../Middleware/EnPlaneta/MsjReceptorApp.h"
#include "../../../Middleware/EnPlaneta/MsjReceptorMid.h"

#include "../../../Framework/Shared/sem.h"
#include "../../../Framework/Shared/shptr.h"

using namespace std;

int main(int argc, char **argv) {

	//creo recursos compartidos
	Semaphore semAccesoInfoPipe;
	if (!semAccesoInfoPipe.init(1))
	{
		cout << "Fallo inicializacion semAccesoInfoPipe. " << endl;
		return -1;
	}

	Semaphore semLeyendoDatos;
	if (!semLeyendoDatos.init(1))
	{
		cout << "Fallo inicializacion semLeyendoDatos. " << endl;
		return -1;
	}

	t_sharedRegistro datosRegitro;
	if (!datosRegitro.allocate())
	{
		cout << "Fallo creacion de datosRegistro. " << endl;
		return -1;
	}

	//creo el "falso" middlewareIO
	MockMiddlewareIO midIO;

	//semaforo de sincronizacion para la prueba
	Semaphore mutex1;
	mutex1.init(0);

	//lanzo los 2 procesos del middleware receptor
	pid_t pidMsjReceptorMid = fork();
	if (pidMsjReceptorMid == 0)
	{
		try
		{
			//ccreo e inicializo el proceso receptor que corre en el middleware
			MsjReceptorMidSingleton::instance().inicializar(&midIO,&semLeyendoDatos,&datosRegitro);

			cout << getpid() << " - Espero a que se terminen de registrar los destinos" << endl;
			//notifico que ya esta creado el receptor
			mutex1.signal();

			MsjReceptorMidSingleton::instance().start();
		}catch (...)
		{
			cout << "Excepcion" << endl;
		}
	}else{
		/* en este proceso se ejecuta el MsjReceptorApp ya que necesita
		 * saber el pid del MsjReceptorMid	 */
		//creo el proceso receptor que corre "en la aplicacion"
		MsjReceptorApp mra;
		mra.inicializar(&semAccesoInfoPipe,&semLeyendoDatos,&datosRegitro,pidMsjReceptorMid);

		//espero a que se cree el MsjReceptorMid antes de intentar registrar los destinos
		mutex1.wait();

		//registro los posibles planetas destinos en el middleware
		for (unsigned i = midIO.CANT_DESTINOS; i--; )
		{
			//obtengo el destino
			IdPlaneta destino = midIO.getDestino(i);

			//genero el nombre del pipe
			stringstream nombrePipe;
			nombrePipe << "fifo" << destino.getUid();

			//registro el destino con su pipe
			mra.registrarPipe(nombrePipe.str().c_str(),destino);
		}

		sleep(5);

		cout << "Libero recursos" << endl;
		//no se usan mas los recursos compartidos
		semAccesoInfoPipe.destroy();
		semLeyendoDatos.destroy();
		datosRegitro.free();

		mutex1.destroy();
	}
}
